// 导入axios
import router from '@/router'
import store from '@/store'
import axios from 'axios'
// 导入提示信息框
import { Message } from 'element-ui'
// 定义一个变量存储存储取消的方法
let cancelArr = []
// 取消所有的响应器------应用场景:当从一个页面切换到另一个页面时,需要把前面所有页面的api请求删除掉
// 因为外部需要引用,所以需要暴露此方法
export function cancleAll () {
  cancelArr.filter(item => {
    // 取消这个请求
    item.fn()
    // 销毁当前请求
    return false
  })
}

// 创建axios副本
export const _axios = axios.create({
  // 设置基地址
  baseURL: process.env.VUE_APP_BASE_API
})
// 请求拦截器
_axios.interceptors.request.use(
  (config) => {
    // // 取消:找出相同的api请求并且把前面相同的api进行取消
    cancelArr = cancelArr.filter(item => {
      // 判断当前的请求是否在前面存储中是否存在,如果存在,把前面的api请求给手动取消掉同时删除掉当前项;不存在的话就不管
      if (item.url === config.url && item.method === config.method) {
        item.fn()
        // 销毁掉当前item的存储的请求
        return false
      }
      // 返回正确的api请求
      return true
    })
    // 在请求拦截加入存储当前请求的取消方法
    // cancleFn是axious内部定义好取消axious取消请求的方法
    config.cancelToken = new axios.CancelToken((cancleFn) => {
      cancelArr.push({
        // 存储请求拦截的路径和方式---便于找出重复的请求的api
        url: config.url,
        method: config.method,
        fn: cancleFn
      })
    })
    // 统一token处理
    config.headers.Authorization = 'Bearer ' + store.state.user.token

    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)
// 请求响应器
_axios.interceptors.response.use(
  (res) => {
    // 统一数据发生错误拦截处理
    // 判断是否请求数据成功
    if (res.data.success) {
      // 数据返回成功。返回数据
      return res.data
    } else {
      // 数据发生错误
      // 报错
      Message.error(res.data.message)
      return Promise.reject(res.data.message)
    }
  },
  (error) => {
    // 判断token是否失效，失效的话删除token，删除用户信息，退回登录页
    if (error.response && error.response.status === 401) {
      store.commit('user/loginout')
      Message.error('登录失效')
      // 拿不到fullpath的值,但可以拿到地址栏的值windo.localtion.href
      const path = window.location.href.split('#')[1]
      router.push(path)
    }
    return Promise.reject(error)
  }
)
